import React, { useEffect, useState } from 'react';
import _ from 'lodash';
import { history } from 'umi';
import { Spin, Empty } from 'antd';
import { combination, atomic, layout } from '@/components/PageDesignerComponents';
import { fetchDesignPageDetail } from '@/services/online/onlinePage';
import { generateSerializedNodes } from '@/pages/online/onlinePage/onlinePageDesign/components/tools';
import { getComponentDisplayName } from '@/utils/utils';

const getComponentDisplayNameWithReal = (component) =>
  getComponentDisplayName(component).replace(/^Real/, '');

const componentMappings = _.assign(
  {},
  ..._.map([...combination, ...atomic, ...layout], ({ realComponent, realComponentWrappers }) => {
    return {
      [getComponentDisplayNameWithReal(realComponent)]: realComponent,
      ..._.assign(
        {},
        ...(_.isArray(realComponentWrappers)
          ? _.map(realComponentWrappers, (component) => ({
              [getComponentDisplayNameWithReal(component)]: component,
            }))
          : []),
      ),
    };
  }),
);

export default () => {
  const [initialLoading, setInitialLoading] = useState(true);
  const [componentTree, setComponentTree] = useState(null);

  useEffect(() => {
    let pageId = '';
    try {
      pageId = window.atob(history.location.pathname.replace(/^\/design\//, ''));
    } catch (e) {
      console.log('base64解析异常', e);
    }
    if (pageId) {
      fetchDesignPageDetail({ pageId })
        .then((res) => {
          try {
            const { nodeTree } = generateSerializedNodes(JSON.parse(res));
            setComponentTree(nodeTree);
          } catch (e) {
            console.log('组件树解析异常', e);
          }
          setInitialLoading(false);
        })
        .catch(() => {
          setInitialLoading(false);
        });
    } else {
      setInitialLoading(false);
    }
  }, []);

  const renderComponent = ({ key, componentName, props, children }) =>
    componentName !== 'PageContainer'
      ? React.createElement(
          componentMappings[componentName] || 'div',
          { key, ...props },
          children && children.length ? children.map(renderComponent) : null,
        )
      : children.map(renderComponent);

  return (
    <Spin spinning={initialLoading}>
      {_.isArray(componentTree) ? (
        componentTree.map(renderComponent)
      ) : (
        <Empty description="暂无内容" />
      )}
    </Spin>
  );
};
